भाग 9 - एन्क्रिप्ट किए गए कार्यक्रमों में प्रवेश करें

मानो या न मानो, एन्क्रिप्टेड डेटा के साथ गणना करना संभव है। दूसरे शब्दों में, ऐसा प्रोग्राम चलाना संभव है जहां प्रोग्राम में सभी चर हैं एन्क्रिप्टेड!

इस ट्यूटोरियल में, हम एन्क्रिप्टेड कम्प्यूटेशन के बहुत ही बुनियादी टूल्स से गुजरने वाले हैं। विशेष रूप से, हम एक लोकप्रिय दृष्टिकोण पर ध्यान केंद्रित करने जा रहे हैं जिसे सिक्योर मल्टी-पार्टी कम्प्यूटेशन कहा जाता है। इस पाठ में, हम सीखेंगे कि एक एन्क्रिप्टेड कैलकुलेटर का निर्माण कैसे करें जो एन्क्रिप्टेड संख्याओं पर गणना कर सकता है।

लेखक:

संदर्भ:

nbTranslate का उपयोग करके अनुवादित

संपादक:

चरण 1: सुरक्षित बहु-पक्षीय संगणना का उपयोग कर एन्क्रिप्शन

SMPC पहली नज़र में "एन्क्रिप्शन" का एक अजीब रूप है। चर को एन्क्रिप्ट करने के लिए सार्वजनिक / निजी कुंजी का उपयोग करने के बजाय, प्रत्येक मान को कई shares में विभाजित किया जाता है, जिनमें से प्रत्येक एक निजी कुंजी की तरह काम करता है। आमतौर पर, ये share 2 या अधिक owners के बीच वितरित किए जाएंगे। इस प्रकार, चर को डिक्रिप्ट करने के लिए, सभी owners को डिक्रिप्शन की अनुमति देने के लिए सहमत होना चाहिए। संक्षेप में, सभी के पास एक निजी कुंजी है।

Encrypt()

तो, मान लें कि हम एक चर 'x' को "एन्क्रिप्ट" करना चाहते हैं, हम निम्नलिखित तरीके से ऐसा कर सकते हैं।

 > एन्क्रिप्शन फ़्लोट्स या वास्तविक संख्याओं का उपयोग नहीं करता है, लेकिन एक गणितीय स्थान में होता है जिसे integer quotient ring कहा जाता है जो मूल रूप से 0 औरQ-1 के बीच पूर्णांक है, जहां Q प्राइम् और "पर्याप्त" है ताकि हमारे प्रयोगों में उपयोग किए जाने वाले सभी नंबर शामिल हो सकें। व्यवहार में, 'x' पूर्णांक को मान देते हुए, हम रिंग में फिट होने के लिए x % Q करते हैं। (इसीलिए हम नंबर x' > Q का उपयोग करने से बचते हैं)।


In [1]:
Q = 1234567891011

In [2]:
x = 25

In [3]:
import random

def encrypt(x):
    share_a = random.randint(-Q,Q)
    share_b = random.randint(-Q,Q)
    share_c = (x - share_a - share_b) % Q
    return (share_a, share_b,  share_c)

In [4]:
encrypt(x)


Out[4]:
(-563135268240, -781596417334, 110163794588)

जैसा कि आप यहां देख सकते हैं, हमने अपने वेरिएबल x को 3 अलग-अलग शेयरों में विभाजित किया है, जिसे 3 अलग-अलग owners (मालिकों) को भेजा जा सकता है।

Decrypt()

यदि हम इन 3 शेयरों को डिक्रिप्ट करना चाहते हैं, तो हम उन्हें एक साथ जोड़ सकते हैं और परिणाम के मापांक (मॉड क्यू) ले सकते हैं।


In [5]:
def decrypt(*shares):
    return sum(shares) % Q

In [6]:
a,b,c = encrypt(25)

In [7]:
decrypt(a, b, c)


Out[7]:
25

महत्वपूर्ण रूप से, ध्यान दें कि यदि हम केवल दो shares के साथ डिक्रिप्ट करने की कोशिश करते हैं, तो डिक्रिप्शन काम नहीं करता है!


In [8]:
decrypt(a, b)


Out[8]:
923879084166

इस प्रकार, हमें मूल्य को डिक्रिप्ट करने के लिए सभी मालिकों की आवश्यकता है। यह इस तरह से है कि shares निजी कुंजी की तरह काम करते हैं, जिनमें से सभी को एक मूल्य को डिक्रिप्ट करने के लिए मौजूद होना चाहिए।

चरण 2: SMPC का उपयोग करके बुनियादी अंकगणित

हालाँकि, सुरक्षित बहु-पक्षीय संगणना की वास्तव में असाधारण संपत्ति है गणना करने की क्षमता जब चर अभी भी एन्क्रिप्ट किए जा रहे हैं। आइए नीचे सरल जोड़ प्रदर्शित करें।


In [9]:
x = encrypt(25)
y = encrypt(5)

In [10]:
def add(x, y):
    z = list()
    # the first worker adds their shares together
    z.append((x[0] + y[0]) % Q)
    
    # the second worker adds their shares together
    z.append((x[1] + y[1]) % Q)
    
    # the third worker adds their shares together
    z.append((x[2] + y[2]) % Q)
    
    return z

In [11]:
decrypt(*add(x,y))


Out[11]:
30

सफलता!!!

आखिर तुमने इसे हासिल कर ही लिया है! यदि प्रत्येक कार्यकर्ता (अलग-अलग) अपने शेयरों को एक साथ जोड़ता है, तो परिणामस्वरूप शेयर सही मूल्य (25 + 5 == 30) के लिए डिक्रिप्ट करेंगे।

जैसा कि यह पता चला है, SMPC प्रोटोकॉल मौजूद हैं जो निम्नलिखित कार्यों के लिए इस एन्क्रिप्टेड संगणना की अनुमति दे सकते हैं:

  • इसके अलावा (जो हमने अभी देखा है)
  • गुणन
  • तुलना

और इन मूल अंतर्निहित प्राथमिकताओं का उपयोग करके, हम मनमानी गणना कर सकते हैं !!!

अगले भाग में, हम इन ऑपरेशनों को करने के लिए PySyft लाइब्रेरी का उपयोग करना सीखेंगे!

चरण 3: SMPC PySyft का उपयोग करना

पिछले खंडों में, हमने SMPC के आसपास कुछ बुनियादी अंतर्ज्ञानों को रेखांकित किया है जो काम करने वाले हैं। हालाँकि, व्यवहार में हम अपने एन्क्रिप्टेड कार्यक्रमों को लिखने के दौरान स्वयं ही सभी आदिम संचालन को हाथ से लिखना नहीं चाहते हैं। इस प्रकार, इस खंड में हम PySyft का उपयोग करते हुए एन्क्रिप्टेड संगणना कैसे करें की मूल बातों से गुजरने वाले हैं। विशेष रूप से, हम इस बात पर ध्यान केंद्रित करने जा रहे हैं कि पहले बताई गई 3 प्रधान बातें कैसे करें: जोड़, गुणा और तुलना।

सबसे पहले, हमें कुछ Virtual Workers (वर्चुअल वर्कर्स) बनाने की ज़रूरत है (जो उम्मीद है कि अब आप हमारे पिछले ट्यूटोरियल दिए गए हैं)।


In [12]:
import torch
import syft as sy
hook = sy.TorchHook(torch)

bob = sy.VirtualWorker(hook, id="bob")
alice = sy.VirtualWorker(hook, id="alice")
bill = sy.VirtualWorker(hook, id="bill")

बुनियादी एन्क्रिप्शन / डिक्रिप्शन

एन्क्रिप्शन किसी भी PySyft टेंसर और calling.share() के रूपांतरण सरल है। डिक्रिप्शन साझा चर पर .get() के रूपांतरण सरल है


In [13]:
x = torch.tensor([25])

In [14]:
x


Out[14]:
tensor([25])

In [15]:
encrypted_x = x.share(bob, alice, bill)

In [16]:
encrypted_x.get()


Out[16]:
tensor([25])

एन्क्रिप्ट किए गए मानों का परिचय

यदि हम बॉब, एलिस और बिल के श्रमिकों के करीब देखते हैं, तो हम उन shares को देख सकते हैं जो बनते हैं!


In [17]:
bob._objects


Out[17]:
{}

In [18]:
x = torch.tensor([25]).share(bob, alice, bill)

In [19]:
# Bob's share
bobs_share = list(bob._objects.values())[0]
bobs_share


Out[19]:
tensor([-2744649627810023233])

In [20]:
# Alice's share
alices_share = list(alice._objects.values())[0]
alices_share


Out[20]:
tensor([-2430621816214436904])

In [21]:
# Bill's share
bills_share = list(bill._objects.values())[0]
bills_share


Out[21]:
tensor([5175271444024460162])

और अगर हम चाहते थे, हम पहले से बात की गई वही दृष्टिकोण का उपयोग करके इन मूल्यों को डिक्रिप्ट कर सकते हैं !!!


In [22]:
(bobs_share + alices_share + bills_share)


Out[22]:
tensor([25])

जैसा कि आप देख सकते हैं, जब हमने .share() कहा तो यह केवल 3 शेयरों में मूल्य को विभाजित करता है और प्रत्येक पक्ष को एक शेयर भेजता है!

एन्क्रिप्टेड अंकगणित

और अब आप देखते हैं कि हम अंतर्निहित मूल्यों पर अंकगणित कर सकते हैं! एपीआई का निर्माण इसलिए किया जाता है ताकि हम अंकगणित का प्रदर्शन सामान्य Pytorch tensors जैसे कर सकें।


In [23]:
x = torch.tensor([25]).share(bob,alice)
y = torch.tensor([5]).share(bob,alice)

In [24]:
z = x + y
z.get()


Out[24]:
tensor([30])

In [25]:
z = x - y
z.get()


Out[25]:
tensor([20])

एन्क्रिप्ट किया गया गुणन

गुणन के लिए हमें एक अतिरिक्त पार्टी की आवश्यकता होती है जो लगातार यादृच्छिक संख्या उत्पन्न करने के लिए ज़िम्मेदार है (और किसी भी अन्य दलों के साथ मिलीभगत नहीं करता है)। हम इस व्यक्ति को "crypto provider" कहते हैं। सभी गहन उद्देश्यों के लिए, crypto provider सिर्फ एक अतिरिक्त VirtualWorker है, लेकिन यह स्वीकार करना महत्वपूर्ण है कि crypto provider एक "मालिक" नहीं है जिसमें वह / उसके पास खुद के शेयर नहीं हैं, लेकिन जिन पर भरोसा किया जा सकता है कि वह मौजूदा शेयरधारकों में से किसी के साथ साँठ गाँठ नहीं करता है।


In [26]:
crypto_provider = sy.VirtualWorker(hook, id="crypto_provider")

In [27]:
x = torch.tensor([25]).share(bob,alice, crypto_provider=crypto_provider)
y = torch.tensor([5]).share(bob,alice, crypto_provider=crypto_provider)

In [28]:
# multiplication

z = x * y
z.get()


Out[28]:
tensor([125])

आप मैट्रिक्स गुणा भी कर सकते हैं


In [29]:
x = torch.tensor([[1, 2],[3,4]]).share(bob,alice, crypto_provider=crypto_provider)
y = torch.tensor([[2, 0],[0,2]]).share(bob,alice, crypto_provider=crypto_provider)

In [30]:
# matrix multiplication

z = x.mm(y)
z.get()


Out[30]:
tensor([[2, 4],
        [6, 8]])

एन्क्रिप्टेड तुलना

निजी मूल्यों के बीच निजी तुलना करना भी संभव है। हम यहां SecureNN प्रोटोकॉल पर भरोसा करते हैं, जिसका विवरण यहां पाया जा सकता है। तुलना का परिणाम एक निजी साझा टेंसर भी है।


In [31]:
x = torch.tensor([25]).share(bob,alice, crypto_provider=crypto_provider)
y = torch.tensor([5]).share(bob,alice, crypto_provider=crypto_provider)

In [32]:
z = x > y
z.get()


Out[32]:
tensor([1])

In [33]:
z = x <= y
z.get()


Out[33]:
tensor([0])

In [34]:
z = x == y
z.get()


Out[34]:
tensor([0])

In [35]:
z = x == y + 20
z.get()


Out[35]:
tensor([1])

आप अधिकतम संचालन भी कर सकते हैं


In [36]:
x = torch.tensor([2, 3, 4, 1]).share(bob,alice, crypto_provider=crypto_provider)
x.max().get()


Out[36]:
tensor([4])

In [37]:
x = torch.tensor([[2, 3], [4, 1]]).share(bob,alice, crypto_provider=crypto_provider)
max_values, max_ids = x.max(dim=0)
max_values.get()


Out[37]:
tensor([4, 3])

बधाई हो!!! - समुदाय में शामिल होने का समय!

इस नोटबुक ट्यूटोरियल को पूरा करने पर बधाई! यदि आपने इसका आनंद लिया है और एआई और एअर सप्लाई चेन (डेटा) के विकेन्द्रीकृत स्वामित्व के संरक्षण की ओर आंदोलन में शामिल होना चाहते हैं, तो आप निम्न तरीकों से ऐसा कर सकते हैं!

GitHub पर स्टार PySyft

हमारे समुदाय की मदद करने का सबसे आसान तरीका सिर्फ रिपोज अभिनीत है! यह हमारे द्वारा बनाए जा रहे कूल टूल्स के बारे में जागरूकता बढ़ाने में मदद करता है।

हमारे Slack में शामिल हों!

नवीनतम प्रगति पर अद्यतित रहने का सबसे अच्छा तरीका हमारे समुदाय में शामिल होना है! http://slack.openmined.org पर फॉर्म भरकर आप ऐसा कर सकते हैं

एक कोड परियोजना में शामिल हों!

हमारे समुदाय में योगदान करने का सबसे अच्छा तरीका एक कोड योगदानकर्ता बनना है! किसी भी समय आप PySyft GitHub जारी करने वाले पृष्ठ पर जा सकते हैं और "Projects" के लिए फ़िल्टर कर सकते हैं। यह आपको सभी शीर्ष स्तर के टिकट दिखाएगा कि आप किन परियोजनाओं में शामिल हो सकते हैं! यदि आप किसी परियोजना में शामिल नहीं होना चाहते हैं, लेकिन आप थोड़ी सी कोडिंग करना चाहते हैं, तो आप "good first issue" के रूप में चिह्नित GitHub मुद्दों की खोज करके अधिक मिनी-प्रोजेक्ट्स की तलाश कर सकते हैं।

दान करना

यदि आपके पास हमारे कोडबेस में योगदान करने का समय नहीं है, लेकिन फिर भी समर्थन उधार देना चाहते हैं, तो आप हमारे ओपन कलेक्टिव में भी एक बैकर बन सकते हैं। सभी दान हमारी वेब होस्टिंग और अन्य सामुदायिक खर्च जैसे कि हैकाथॉन और मीटअप की ओर जाते हैं!

OpenMined का ओपन कलेक्टिव पेज


In [ ]: